package pri.damai.xiaowu.auth.security.config;

import pri.damai.xiaowu.auth.security.authorization.RuiRuanAuthenticationTokenProvider;
import pri.damai.xiaowu.auth.security.filter.RuiRuanAuthenticationProcessingFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import pri.damai.xiaowu.auth.security.handle.*;
import pri.damai.xiaowu.common.security.config.XiaoWuSecurityProperties;

import javax.annotation.Resource;
import java.util.List;

/**
 * Security 配置
 * @Desc
 * @Author DaMai
 * @Date 2021/7/15 14:21
 * 但行好事，莫问前程。
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    RuiRuanAuthenticationTokenProvider ruiRuanAuthenticationTokenProvider;
    @Resource
    RuiRuanAuthenticationSuccessHandler ruiRuanAuthenticationSuccessHandler;
    @Resource
    RuiRuanAuthenticationFailureHandler ruiRuanAuthenticationFailureHandler;
    @Resource
    RuiRuanAuthenticationEntryPoint ruiRuanAuthenticationEntryPoint;
    @Resource
    RuiRuanLogoutHandler ruiRuanLogoutHandler;
    @Resource
    RuiRuanLogoutSuccessHandler ruiRuanLogoutSuccessHandler;
    @Resource
    XiaoWuSecurityProperties securityProperties;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // 放行指定接口
        List<String> notLoginUrls = securityProperties.getNotLoginUrls();

        // 关闭 session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // 替换原有认证入口filter
        http.addFilterAt(myAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);

        // 配置认证
        http.authorizeRequests()
                .antMatchers(notLoginUrls.toArray(new String[0]))
                .permitAll()
                .antMatchers(securityProperties.getLoginUrl())
                .authenticated()
                .and()
                .logout()
                .logoutUrl(securityProperties.getLogoutUrl())
                .addLogoutHandler(ruiRuanLogoutHandler)
                .logoutSuccessHandler(ruiRuanLogoutSuccessHandler)
                .and()
                .csrf()
                .disable();

        // 未认证处理器
        http.exceptionHandling().authenticationEntryPoint(ruiRuanAuthenticationEntryPoint);
    }

    /**
     * 认证入口配置
     * @apiNote [附加描述]
     * @return com.ruiruan.ruiruanpreauth.filter.RuiRuanAuthenticationProcessingFilter
     * @author DaMai
     * @date 2021/10/13 18:30
     */
    private RuiRuanAuthenticationProcessingFilter myAuthenticationProcessingFilter() {

        RuiRuanAuthenticationProcessingFilter filter = new RuiRuanAuthenticationProcessingFilter();

        filter.setAuthenticationSuccessHandler(ruiRuanAuthenticationSuccessHandler);

        filter.setAuthenticationFailureHandler(ruiRuanAuthenticationFailureHandler);

        filter.setAuthenticationManager(new ProviderManager(ruiRuanAuthenticationTokenProvider));

        filter.setFilterProcessesUrl(securityProperties.getLoginUrl());

        return filter;
    }
}
